package nettydemo;/*

 */

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;

/**
 * @ClassName NIOServer
 * @Author Final
 * @Project DataStructures
 */
public class NIOServer {

    public static void main(String[] args) throws IOException {
        //创建serversocketChannel -》 serverSocket
        ServerSocketChannel open = ServerSocketChannel.open();

        //得到一个selector
        Selector selector= Selector.open();

        //绑定一个端口
        open.socket().bind(new InetSocketAddress(801));

        //设置非阻塞
        open.configureBlocking(false);
        //把serversocketChannel注册到selector ，关心事件为op_accept
        open.register(selector, SelectionKey.OP_ACCEPT);

        //等待客户端连接循环

        while (true){

            if (selector.select(1000)==0){
                System.out.println("等待了一秒，无连接");
                continue;
            }

            //如果返回的不是0,就会去到相关的selectionkey集合
            //1、如果返回》0，表示已经获取到关注的事件
            //2、selector。selectedkey（）返回关注事件的集合，通过selectionkeys反向获取通道
            Set<SelectionKey> selectionKeys = selector.selectedKeys();

            //遍历set《selectionkey》

            Iterator<SelectionKey> keyIterator = selectionKeys.iterator();

            while (keyIterator.hasNext()){
                //获取到selectionkey
                SelectionKey nextKey = keyIterator.next();

                //根绝key，对应的通发生的事件做响应处理
                if (nextKey.isAcceptable()){
                    //给该客户端生成一个socketChannel
                    SocketChannel acceptChannel = open.accept();
                    System.out.println("客户端连接");
                    //将acceptCHannel设置为非阻塞
                    acceptChannel.configureBlocking(false);
                    //将acceptChannel注册到selector 同时给acceptChannel
                    open.register(selector,SelectionKey.OP_ACCEPT, ByteBuffer.allocate(1024));

                }
                //发生op_read
                if (nextKey.isReadable()){
                    //通过key反向获取对应的channel
                    SocketChannel channel = (SocketChannel)nextKey.channel();
                    //获取到channel关联的buffer
                    ByteBuffer attachment = (ByteBuffer)nextKey.attachment();

                    channel.read(attachment);
                    System.out.println("Fom客户端"+ new String(attachment.array()));
                }
                //手动从集合中移除档期啊你的key，防止重复操作

            }
        }
    }
}
